package com.subfg.payment.aspect;


import com.alibaba.fastjson.JSONObject;
import com.subfg.common.entity.common.CommonResult;
import com.subfg.common.util.network.NetworkUtil;
import com.subfg.payment.aspect.util.ResultAspectUtil;
import com.subfg.payment.constant.ConstantEnum;
import com.subfg.payment.constant.UriDesciptionEnum;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class ResultAspect {
    private Logger log = LoggerFactory.getLogger(ResultAspect.class);

    @Autowired
    private ResultAspectUtil aspectUtil;

    @Pointcut("execution(* com.subfg.payment.controller..*(..))")
    public void excudeService() {
    }

    @Around("excudeService()")
    public <T>T oAround(ProceedingJoinPoint pjp) {
        //接口请求开始时间
        Long startRequestTime = System.currentTimeMillis();
        // 获取请求数据
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取类包名
        String pageName = pjp.getTarget().getClass().getPackage().getName();
        // 获取类名
        String className = pjp.getTarget().getClass().getName();
        // 获取请求参数
        Object[] args = pjp.getArgs();
        // 获取客户端的ip地址
        String userIp = NetworkUtil.getIPAddress(request);
        // 赋值默认的连接
        UriDesciptionEnum uriDesciptionEnum = UriDesciptionEnum.INIT_URIDESCIPTION;
        // 返回值
        CommonResult reslutParam = new CommonResult();
        // 区分
        Integer differe = 0;
        // 将请求参数转换为字符串
        String requestParam = JSONObject.toJSONString(args[0]);
        try {
            uriDesciptionEnum = UriDesciptionEnum.fromCode(request.getRequestURI());
            if (aspectUtil.payCallBackClassVeify(className)) {
                differe = 1;
                aspectUtil.insertActionDevice(reslutParam, requestParam, uriDesciptionEnum, userIp, request,  differe, startRequestTime);
                return (T) pjp.proceed();
            } else {
                reslutParam = (CommonResult) pjp.proceed();
            }
        } catch (Throwable e) {
            String exceptionName = e.getClass().getName();
            if (aspectUtil.exceptionClassJudgeVerfiy(exceptionName)) {
                String systemExceptionInform = e.getMessage();
                log.info("可预测的异常,请求接口为==>{}, 客户端请求检验错误==>{}", uriDesciptionEnum.getApiName(), systemExceptionInform);
                reslutParam = CommonResult.error(systemExceptionInform);
            } else {
                log.error("服务处理异常, 请求接口==>>>{}, 错误内容==>>>{}",  uriDesciptionEnum.getApiName(), e);
                ConstantEnum constantEnum = ConstantEnum.SYSTEM_UNKNOWN;
                reslutParam = CommonResult.error(constantEnum.getCode(), constantEnum.getMessage());
            }
        } finally {
            try {
                aspectUtil.insertActionDevice(reslutParam, requestParam, uriDesciptionEnum, userIp, request,  differe, startRequestTime);
            } catch (Exception e) {
                String systemExceptionInform = e.getMessage();
                log.error("如库队列赋值错误"+e);
                log.error("最后写入出现异常!!!请求接口为==>{}, 客户端请求检验错误==>{}", uriDesciptionEnum.getApiName(), systemExceptionInform);
            }
        }
        return (T) reslutParam;
    }
}
